#include <iostream>
#include <stdexcept>

template <typename T>
class MyQueue {
private:
    // 链表节点定义
    struct Node {
        T data;
        Node* next;
        Node(const T& data) : data(data), next(NULL) {}
    };

    Node* front;  // 队头指针
    Node* rear;   // 队尾指针
    size_t count; // 元素计数

public:
    // 构造函数
    MyQueue() : front(NULL), rear(NULL), count(0) {}

    // 析构函数
    ~MyQueue() {
        clear();
    }

    // 拷贝构造函数
    MyQueue(const MyQueue& other) : front(NULL), rear(NULL), count(0) {
        Node* temp = other.front;
        while (temp != NULL) {
            enqueue(temp->data);
            temp = temp->next;
        }
    }

    // 赋值运算符
    MyQueue& operator=(const MyQueue& other) {
        if (this != &other) {
            clear();
            Node* temp = other.front;
            while (temp != NULL) {
                enqueue(temp->data);
                temp = temp->next;
            }
        }
        return *this;
    }

    // 入队操作
    void enqueue(const T& item) {
        Node* newNode = new Node(item);
        if (isEmpty()) {
            front = rear = newNode;
        } else {
            rear->next = newNode;
            rear = newNode;
        }
        count++;
    }

    // 出队操作
    T dequeue() {
        if (isEmpty()) {
            throw std::underflow_error("队列为空，无法出队");
        }
        T item = front->data;
        Node* temp = front;
        front = front->next;
        delete temp;
        count--;
        
        if (front == NULL) {
            rear = NULL;
        }
        return item;
    }

    // 获取队首元素（不删除）
    T peek() const {
        if (isEmpty()) {
            throw std::underflow_error("队列为空，无法获取队首元素");
        }
        return front->data;
    }

    // 检查队列是否为空
    bool isEmpty() const {
        return count == 0;
    }

    // 获取队列当前元素数量
    size_t size() const {
        return count;
    }

    // 清空队列
    void clear() {
        while (!isEmpty()) {
            dequeue();
        }
    }
};

// 测试代码
int main() {
    MyQueue<int> queue;  // 创建一个整型队列

    // 测试入队
    queue.enqueue(10);
    queue.enqueue(20);
    queue.enqueue(30);
    std::cout << "队首元素: " << queue.peek() << std::endl;
    std::cout << "队列大小: " << queue.size() << std::endl;

    // 测试出队
    std::cout << "出队元素: " << queue.dequeue() << std::endl;
    std::cout << "出队后队首元素: " << queue.peek() << std::endl;

    // 测试拷贝构造
    MyQueue<int> queue2 = queue;
    std::cout << "拷贝构造后的队列大小: " << queue2.size() << std::endl;

    // 测试赋值运算符
    MyQueue<int> queue3;
    queue3 = queue;
    std::cout << "赋值后的队列大小: " << queue3.size() << std::endl;

    // 测试清空队列
    queue.clear();
    std::cout << "清空后队列大小: " << queue.size() << std::endl;

    return 0;
}